
/**
 * 事件助手
 * 
 * @param {Object} context 事件上下文, 调用 addEvent，removeEvent 等方法时，会使用该上下文
 * @param {Object} options 配置
 * @param {Function} options.addEvent 注册事件方法
 * @param {Function} options.removeEvent 移除事件方法
 */
export default class EventHelper {

  static classType = 'EventHelper';
  get classType() {
    return EventHelper.classType;
  }

  _context = window;
  _addEvent = null;
  _removeEvent = null;
  _keyIndex  = 0;
  _targetIndex  = 1;
  _events = {};

  constructor(context, options={}){
    let self = this;
    if (options.addEvent){
      self._addEvent = options.addEvent;
    }
    if (options.removeEvent){
      self._removeEvent = options.removeEvent;
    }
    self._keyIndex = options.keyIndex || 0;
    self._targetIndex = options.targetIndex || 1;

    self.context = context;
  }

  set context(context){
    let self = this;
    self._context = context;
    if (!self._addEvent){
      self._addEvent = context.addEventListener;
    }
    if (!self._removeEvent){
      self._removeEvent = context.removeEventListener;
    }
  }
  set addEvent(addEvent){
    this._addEvent = addEvent;
  }
  set removeEvent(removeEvent){
    this._removeEvent = removeEvent;
  }

  on(...args){
    let self = this;
    let key = args[self._keyIndex];
    let target = args[self._targetIndex];
    let events = self._events[key];
    if (!events){
      events = new Set();
      self._events[key] = events;
    }
    events.add(target);
    this._addEvent.apply(this._context, args);
  }
  off(...args){
    let self = this;
    let key = args[self._keyIndex];
    let target = args[self._targetIndex];
    let events = self._events[key];
    if (target){
      if (events) {
        events.delete(target);
      }
      self._removeEvent.apply(self._context, args);
    } else {
      let events = self._events[key];
      delete self._events[key];
      Array.from(events).forEach(event=>{
        args[self._targetIndex] = event;
        self._removeEvent.apply(self._context, args);
      });
    }
  }

  clear() {
    let self = this;
    for(let key in self._events){
      let events = self._events[key];
      Array.from(events).forEach(event => {
        let args = [key, event];
        self._removeEvent.apply(self._context, args);
      });
    }
    self._events = {};
  }

};